/**
 * 
 * @param {Function} fn 需要防抖处理的函数
 * @param {Number} delay 延时时间
 * @param {Function} resultCallback 传入回调获取fn的返回值
 * @param {Boolean} immediate 是否立即执行
 * @returns 
 */
export default function (fn, delay, resultCallback, immediate = false) {
  let timer = null
  // 本轮连续触发是否执行过
  let isInvoke = false
  const _debounce = function (...args) {
    return new Promise((resolve, reject) => {
      if (timer) clearTimeout(timer)
      if (immediate && !isInvoke) {
        try {
          const res = fn.apply(this, args)
          if (resultCallback) resultCallback(res)
          resolve(res)
        } catch (error) {
          reject(error)
        }
        isInvoke = true
      } else {
        timer = setTimeout(() => {
          try {
            const res = fn.apply(this, args)
            if (resultCallback) resultCallback(res)
            resolve(res)
          } catch (error) {
            reject(error)
          }
          isInvoke = false
        }, delay)
      }
    })
  }
  _debounce.cancel = function () {
    if (timer) clearTimeout(timer)
    timer = null
    isInvoke = false
  }
  return _debounce
}